'use strict';
var Promise = require('bluebird')
var fs = require('fs')
var request = Promise.promisify(require('request'))
var axios = require('axios')
var  util = require('./util')
//增加url配置项
var prefix = 'https://api.weixin.qq.com/cgi-bin/';
var api = {
    accessToken: prefix + 'token?grant_type=client_credential',
    selfMenu: prefix+'menu/create?',
    groups:{
        create:prefix+'groups/create?',  //access_token=ACCESS_TOKEN  创建分组，POST请求
        get:prefix+'groups/get?',        //access_token=ACCESS_TOKE  查询所有分组,GET请求
        getId:prefix+'groups/getid?',    //access_token=ACCESS_TOKEN  查询用户所在分组,POST请求
        update:prefix+'groups/update?',  //access_token=ACCESS_TOKEN  修改分组名,POST请求
        membersUpdate:prefix+'groups/members/update?',  //access_token=ACCESS_TOKEN  移动用户分组,POST请求
        membersBatchupdate:prefix+'groups/members/batchupdate?', //access_token=ACCESS_TOKEN  批量移动用户分组,POST请求
        delete:prefix+'groups/delete?'   //access_token=ACCESS_TOKEN  删除分组,POST请求
    },
    tag:{
    	create:prefix+'tags/create?',//创建标签
    	get:prefix+'tags/get?',//获取公众号已创建的标签
   		update:prefix+'tags/update?',//编辑标签
    	delete:prefix+'tags/delete?',//删除标签
    	getTagUsers:prefix+'tag/get?',//获取标签下粉丝列表
    	batchtagging:prefix+'tags/members/batchtagging?',//批量为用户打标签
    	batchuntagging:prefix+'tags/members/batchuntagging?',//批量为用户取消标签
    	getidlist:prefix+'tags/getidlist?',// 获取用户身上的标签列表
    },
    users:{
        updateremark:prefix+'user/info/updateremark?',  //access_token=ACCESS_TOKEN  备注名
        get:prefix+'user/get?'
    },
    ticke:{
        getticket:prefix+'ticket/getticket?',//access_token=ACCESS_TOKEN&type=jsapi
    },
    mass:{
        sendall:prefix+'message/mass/sendall?',  //access_token=ACCESS_TOKEN 群发消息
        sendTagAll:prefix+'message/mass/sendall?'//根据标签进行群发
    },
    material:{
        uploadMaterial : prefix + 'media/upload?' ,  //上传临时素材 access_token=ACCESS_TOKEN&type=TYPE
        uploadPermMaterial:{   // 上传永久素材
            uploadPermPics:prefix + 'media/uploadimg?',
            uploadPermNews:prefix + 'material/add_news?',
            uploadPermOther:prefix + 'material/add_material?',
        },
        getPermMaterial:prefix + 'material/get_material?', //获取永久素材
        getTempMaterial:prefix + 'media/get?', //获取临时素材
        delPermMaterial:prefix + 'material/del_material?', //删除永久素材
        batchgetMaterial:prefix + 'material/batchget_material??', //获取永久素材列表
    },

    uploadnews:prefix+'media/uploadnews?',  //access_token=ACCESS_TOKEN 群发消息  上传图文消息接口
    prefixcode:'https://api.weixin.qq.com/sns/oauth2/access_token?', //appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    userinfo:'https://api.weixin.qq.com/sns/userinfo?' //access_token=ACCESS_TOKEN&openid=OPENID 获取用户信息
}

//利用构造函数生成实例 完成票据存储逻辑
function Wechat(opts) {
    var that = this;
    this.appID = opts.appID;
    this.appSecret = opts.appSecret;
    this.getAccessToken = opts.getAccessToken;
    this.saveAccessToken = opts.saveAccessToken;
    this.getJsapiTicketToken = opts.getJsapiTicketToken;
    this.saveJsapiTicketToken = opts.saveJsapiTicketToken;
    this.fetchAccessToken();
    
};
//在weChat的原型链上增加获取票据的方法
Wechat.prototype.fetchAccessToken = function(cb) {
     
    var that = this
   
     if(this.access_token&&this.expires_in){
         if(this.isValidAccessToken(this)){
            cb&&cb(this);
            //return Promise.resolve(this)
         }
     }
    
      //获取票据的方法
      this.getAccessToken()
      .then(function(data) {
    
          //从静态文件获取票据，JSON化数据，如果有异常，则尝试更新票据
          try {
              data = JSON.parse(data);
          } catch (e) {
              return that.updateAccessToken();
          }
          //判断票据是否在有效期内，如果合法，向下传递票据，如果不合法，更新票据
          if (that.isValidAccessToken(data)) {
              return  new Promise(function(resolve, reject){
                resolve(data)
                    }
                )
            //Promise.resolve(data);
          } else {
              return that.updateAccessToken();
          }
      })
      .then(function(data){
          //Promise.resolve(data)
           
            that.access_token = data.access_token;
            that.expires_in = data.expires_in;
            that.saveAccessToken(data);
            cb&&cb(data);
        //    return  new Promise(function(resolve, reject){
        //             resolve(data)
        //            }
        //     )
      })
};
//在weChat的原型链上增加验证有效期的方法
Wechat.prototype.isValidAccessToken = function(data) {
    //进行判断，如果票据不合法，返回false
    if (!data || !data.access_token || !data.expires_in) {
        return false;
    }
    //拿到票据和过期时间的数据
    var access_token = data.access_token;
    var expires_in = data.expires_in;
    //获取当前时间
    var now = (new Date().getTime());
    //如果当前时间小于票据过期时间，返回true，否则返回false
    if (now < expires_in) {
        return true;
    } else {
        return false;
    };
};

//在weChat的原型链上增加更新票据的方法
Wechat.prototype.updateAccessToken = function() {
    var appID = this.appID;
    var appSecret = this.appSecret;
    var url = api.accessToken + '&appid=' + appID + '&secret=' + appSecret;

    return new Promise(function(resolve, reject) {
        //使用request发起请求
        request({
            url: url,
            json: true
        }).then(function(response) {
           // console.log(response.body)
            var data = response.body;
            var now = (new Date().getTime());
            var expires_in = now + (data.expires_in - 20) * 1000;
            //把新票据的有效时间赋值给data
            data.expires_in = expires_in;
            
            resolve(data);
        })
    })
};

//在weChat的原型链上增加自定义菜单接口的方法
Wechat.prototype.selfMenu = function() {
    var that =this
    var form ={
        "button":[
            {    
                "type":"view",
                "name":"测试1",
                "url":"http://122.112.213.124/wxweb"
             },
             {    
                "type":"view",
                "name":"请领单",
                "url":"http://122.112.213.124:3000/wx_login"
             }
            ]
         
    }
    that.fetchAccessToken(function(data){
        var url = api.selfMenu + 'access_token='+data.access_token;
        return new Promise(function(resolve, reject) {
            axios({
                method: 'post',
                url: url,
                data: form
            }).then(function(response) {
                var _data = response.data;
                if(_data.errmsg!=='ok'){
                throw new Error('errcode:'+_data.errcode+'  errmsg:'+_data.errmsg)}
            }).catch(function(err){
                reject(err)
            })
        })

    })
     

};

//获取用户列表
Wechat.prototype.getUserList = function(NEXT_OPENID){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            NEXT_OPENID = NEXT_OPENID?NEXT_OPENID:'';
            var url = api.users.get + 'access_token=' + data.access_token+'&next_openid='+NEXT_OPENID;//access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
            
            request({method:'GET',url:url,json:true}).then(function(response){
                var _data = response.body;
                if(_data.count>0){
                   resolve(_data.data.openid);
                }
                else{
                        throw new Error('create group failed: ' + _data.errmsg);
                }
            }).catch(function(err){
                 reject(err);
            })
        })
    })
}




//创建用户分组
Wechat.prototype.createGroup = function(name){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
         
            var url = api.groups.create + 'access_token=' + data.access_token;
            var opts = {
                group:{
                    name:name
                }
            };
            request({method:'POST',url:url,body:opts,json:true}).then(function(response){
                var _data = response.body;
                if(_data.group){
                   resolve(_data.group);
                    }else{
                        throw new Error('create group failed: ' + _data.errmsg);
                    }
                }).catch(function(err){
                    reject(err);
                });
            });
    });
}

//获取用户分组
Wechat.prototype.getGroups = function(name){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = api.groups.get + 'access_token=' + data.access_token;
            request({url:url,json:true}).then(function(response){
                var _data = response.body;
                if(_data.groups){
                    _data.groups.forEach(element => {
                        if(element.name === name){
                            resolve(element);
                        }
                    });
                    
                    }else{
                        throw new Error('create group failed: ' + _data.errmsg);
                    }
                }).catch(function(err){
                    reject(err);
                });
            });

    });
}  

//删除用户分组
Wechat.prototype.deleteGroups = function(idArr){    
         var that = this;
         return new Promise(function(resolve,reject){
            that.fetchAccessToken(function(data){
                var queue = [];
                for(var i = 0; i < idArr.length; i++){
                    queue.push(_deleteGroup(data.access_token,idArr[i]));
                }
                Promise.all(queue).then(function(data){
                    console.log('data:' + data);
                }).catch(function(err){
                    console.log(err)
                })
            });
        })
    }

var _deleteGroup = function(access_token,id){
    var url = api.groups.delete + 'access_token=' + access_token;
    var opts = {
        group:{
            id:id
        }
    };
    return new Promise(function(resolve,reject){
        request({method:'POST',url:url,body:opts,json:true}).then(function(response){
            return response.body 
        });
    });
}
//批量为用户打标签
Wechat.prototype.muchToUserBatchtagging = function(openid_list,tagid){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fecthAccessToken(function(data){
            var url = api.tag.batchtagging + 'access_token=' + data.access_token;
            var form = {
            	"openid_list" :openid_list,
				"tagid" : tagid 
            }
            request({method:'POST',url:url,body:form,json:true}).then(function(response){
                console.log(response.body)
            });
        });
    });
}
//获取标签下的用户
Wechat.prototype.getTagUsers = function(tagid,next_openid){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fecthAccessToken(function(data){
            var url = api.tag.getTagUsers + 'access_token=' + data.access_token;
            next_openid = next_openid?next_openid:"";
            var form = {
            	"tagid" : tagid ,
            	"next_openid" :next_openid,
            }
            
            request({method:'GET',url:url,qs:form,json:true}).then(function(response){
                console.log(response.body)
            });
        });
    });
}
//为用户创建标签
Wechat.prototype.createTag = function(name){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fecthAccessToken(function(data){
            var url = api.tag.create + 'access_token=' + data.access_token;
            var form = {
            	 "tag" : {     "name" : name   }
            }
            request({method:'POST',url:url,body:form,json:true}).then(function(response){
                console.log(response.body)
            });
        });
    });
 
//用户备注名
Wechat.prototype.updateUserRemark = function(openid,remark){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = api.users.updateremark + 'access_token=' + data.access_token;
            var form = {
                openid:openid,
                remark:remark
            };
            request({method:'POST',url:url,body:form,json:true}).then(function(response){
                console.log(response.body)
            });
        });
    });
}

//上传临时素材
Wechat.prototype.uploadTempMaterial = function(type,filepath){
    var that = this;
    var form = {  //构造表单
        media:fs.createReadStream(filepath)
    }
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){

            var url = api.material.uploadMaterial + 'access_token=' + data.access_token + '&type=' + type;
            request({url:url,method:'POST',formData:form,json:true}).then(function(response){
                var _data = response.body;
                if(_data){
                    resolve(_data)
                }else{
                    throw new Error('upload material failed!');
                }
            }).catch(function(err){
                reject(err);
            });
        });
    });
}

//上传永久素材接口
Wechat.prototype.uploadPermMaterial = function(type,filepath){
    var that = this;
    var form = {}
    var uploadUrl = '';
    if(type === 'pic') uploadUrl = api.material.uploadPermMaterial.uploadPermPics;
    if(type === 'other') uploadUrl = api.material.uploadPermMaterial.uploadPermOther;
    if(type === 'news'){
        uploadUrl = api.material.uploadPermMaterial.uploadPermNews;
        form = filepath
    }else{
        form.media = fs.createReadStream(filepath);
    }
   
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = uploadUrl + 'access_token=' + data.access_token;
            var opts = {
                method:'POST',
                url:url,
                json:true
            }
            if(type === 'news'){
                opts.body = form
            }else{
                opts.formData = form 
            }
           // (type == 'news')  ? (opts.body = form) : (opts.formData = form); //上传数据的方式不同
            
            request(opts).then(function(response){
                
                var _data = response.body;
                if(_data){
                    resolve(_data)
                }else{
                    throw new Error('upload permanent material failed!');
                }
            }).catch(function(err){
                reject(err);
            });
        });
    });
}
//获取素材链接
Wechat.prototype.getMaterial = function(mediaId,permanent){
    var that = this;
    var getUrl = permanent ? api.material.getPermMaterial : api.material.getTempMaterial;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = getUrl + 'access_token=' + data.access_token;
            if(!permanent) url += '&media_id=' + mediaId;
            resolve(url)
        });
    });
}
//获取永久素材列表
Wechat.prototype.batchgetMaterial = function(type,offset,count){
    var that = this;
    
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = api.material.batchgetMaterial + 'access_token=' + data.access_token;
            var form={
                "type":type,
                "offset":offset,
                "count":count
            };
            request({method:'POST',url:url,body:form,json:true}).then(function(response){
                
                var _data = response.body;
                
                if(_data){
                    resolve(_data)
                }else{
                    throw new Error('get permanent material failed!');
                }
            }).catch(function(err){
                reject(err);
            });
        });
    });
}

//删除永久素材

Wechat.prototype.delMaterial = function(mediaId){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = api.material.delPermMaterial + 'access_token=' + data.access_token;
            var form = {media_id:mediaId}
            request({url:url,method:'POST',formData:form,json:true}).then(function(response){
                var _data = response.body;
                if(_data.errcode === 0){
                    resolve();
                }else{
                    throw new Error('delete permanent material failed!');
                }
            }).catch(function(err){
                reject(err);
            });
        });
    });
}
Wechat.prototype.sendTagAll=function(type,tag_id,CONTENT){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fecthAccessToken(function(data){
            var url = api.mass.sendTagAll + 'access_token=' + data.access_token;
            var form = {
			   "filter":{
			      "is_to_all":false,
			      "tag_id":tag_id
			   },
			   "msgtype":type
            }
            witch(type)
			{
			case 'text':
			 	form.type={
			 		"content":CONTENT
			 	}
			  break;
			case "voice":
			  form.type={
			 		"media_id":CONTENT
			 	}
			  break;
			case "image":
			  form.type={
			 		"media_id":CONTENT
			 	}
			  break;
			}
            request({method:'POST',url:url,body:form,json:true}).then(function(response){
                console.log(response.body)
            });
        });
    });
}
//群发接口
Wechat.prototype.massSendMsg = function(type,message,groupid){
    var that = this;
    var msg = {
        filter:{},
        msgtype:type
    }
    if(!groupid){
        msg.filter.is_to_all = true
    }else{
        msg.filter.is_to_all = false;
        msg.filter.group_id = groupid;
    }
    msg[type] = message;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = api.mass.sendall + 'access_token=' +data.access_token;
            request({method:'POST',url:url,body:msg,json:true}).then(function(response){
                
                var _data = response.body;
                console.log(response)
                if(_data.errcode === 0){
                    resolve(_data);
                }else{
                    throw new Error('send mass message failed: ' + _data.errmsg);
                }
            }).catch(function(err){
                reject(err);
            });
        });
    });
}


//http GET方式请求获得jsapi_ticket
Wechat.prototype.getJsapi_ticket = function(openid,remark){
    var that = this;
    return new Promise(function(resolve,reject){
        that.fetchAccessToken(function(data){
            var url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='+data.access_token+'&type=jsapi';
            
            request({url:url,json:true}).then(function(response){
                console.log(response.body)
            });
        });
    });
}


//在weChat的原型链上增加获取jsapi_ticket的方法
Wechat.prototype.fecthJsapiTicketToken = function(cb) {
     
    var that = this
     
     if(this.Jsapi_ticket_token&&this.Jsapi_ticket_expires_in){
         if(this.isValidJsapiTicketToken(this)){
            cb&&cb(this);
           // return Promise.resolve(this)
         }
     }
    
      //获取票据的方法
      this.getJsapiTicketToken()
      .then(function(data) {
    
          //从静态文件获取票据，JSON化数据，如果有异常，则尝试更新票据
          try {
              data = JSON.parse(data);
             
          } catch (e) {
            
              return that.updateJsapiTicketToken();
          }
          //判断票据是否在有效期内，如果合法，向下传递票据，如果不合法，更新票据
          if (that.isValidJsapiTicketToken(data)) {
              return  new Promise(function(resolve, reject){
                    resolve(data)
                    }
                )
            //Promise.resolve(data);
          } else {
              return that.updateJsapiTicketToken();
          }
      })
      .then(function(data){
          //Promise.resolve(data)
            that.Jsapi_ticket_token = data.ticket;
            that.Jsapi_ticket_expires_in = data.expires_in;
            that.saveJsapiTicketToken({'ticket':data.ticket,'expires_in':data.expires_in});
            cb&&cb(data);
        //    return  new Promise(function(resolve, reject){
        //             resolve(data)
        //            }
        //     )
      })
};
//在weChat的原型链上增加验证有效期的方法
Wechat.prototype.isValidJsapiTicketToken = function(data) {
    //进行判断，如果票据不合法，返回false
    if (!data || !data.Jsapi_ticket_token || !data.Jsapi_ticket_expires_in) {
        return false;
    }
    //拿到票据和过期时间的数据
    var Jsapi_ticket_token = data.ticket;
    var Jsapi_ticket_expires_in = data.expires_in;
    //获取当前时间
    var now = (new Date().getTime());
    //如果当前时间小于票据过期时间，返回true，否则返回false
    if (now < Jsapi_ticket_expires_in) {
        return true;
    } else {
        return false;
    };
};

//在weChat的原型链上增加更新票据的方法
Wechat.prototype.updateJsapiTicketToken = function() {
    var that = this;
    return new Promise(function(resolve, reject) {
        that.fetchAccessToken(function(data){
            var url = api.ticke.getticket + 'access_token='+data.access_token+'&type=jsapi';
            //使用request发起请求
            request({
                url: url,
                json: true
            }).then(function(response) {
                
                var data = response.body;
                var now = (new Date().getTime());
                var Jsapi_ticket_expires_in = now + (data.expires_in - 20) * 1000;
                //把新票据的有效时间赋值给data
                data.expires_in =Jsapi_ticket_expires_in;
                resolve(data);
            })
        });
       
    })
};

//http GET方式请求获得网页授权access_token
Wechat.prototype.fecthOAuthAccessToken = function(CODE){
    var that = this;
    return new Promise(function(resolve,reject){
        var url = api.prefixcode+'appid='+that.appID+'&secret='+that.appSecret+'&code='+CODE+'&grant_type=authorization_code';
        
        request({url:url,json:true}).then(function(response){
            resolve(response.body)
        });
         
    });
}

//http GET方式请求获得用户信息
Wechat.prototype.getUserinfo = function(data){
    var that = this;
    return new Promise(function(resolve,reject){
        var url = api.userinfo+'access_token='+data.access_token+'&openid='+data.openid;
        
        request({url:url,json:true}).then(function(response){
            resolve(response.body)
        });
    })
    
}

//在weChat的原型链上增加验证网页授权有效期的方法
Wechat.prototype.isValidOAuthAccessToken = function(data) {
    //进行判断，如果票据不合法，返回false
    if (!data || !data.Jsapi_ticket_token || !data.Jsapi_ticket_expires_in) {
        return false;
    }
    //拿到票据和过期时间的数据
    var Jsapi_ticket_token = data.ticket;
    var Jsapi_ticket_expires_in = data.expires_in;
    //获取当前时间
    var now = (new Date().getTime());
    //如果当前时间小于票据过期时间，返回true，否则返回false
    if (now < Jsapi_ticket_expires_in) {
        return true;
    } else {
        return false;
    };
};

//在weChat的原型链上增加网页授权更新票据的方法
Wechat.prototype.updateOAuthAccessToken = function() {
    var that = this;
    return new Promise(function(resolve, reject) {
        that.fetchAccessToken(function(data){
            var url = api.ticke.getticket + 'access_token='+data.access_token+'&type=jsapi';
            //使用request发起请求
            request({
                url: url,
                json: true
            }).then(function(response) {
                
                var data = response.body;
                var now = (new Date().getTime());
                var Jsapi_ticket_expires_in = now + (data.expires_in - 20) * 1000;
                //把新票据的有效时间赋值给data
                data.expires_in =Jsapi_ticket_expires_in;
                resolve(data);
            })
        });
       
    })
};


Wechat.prototype.reply =  function(){
    if(!!!this.body){
        return false
    }
    var content = this.body
    var message = this.weixin
    var xml = util.tpl(content,message)
   
    this.status = 200;
    this.type = 'application/xml';
    this.body = xml;
    
}



module.exports = Wechat;